/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SLE_SSAP_SERVER_HAL_H
#define SLE_SSAP_SERVER_HAL_H

#ifndef SLE_LOG_TAG
#define SLE_LOG_TAG "[SleHal]"
#endif

#include <stddef.h>
#include <stdlib.h>
#include "sle_ssap_server_hdi.h"
#include "sle_ssap_server_config.h"
#include "sle_hal_errcode.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief       Sle ssap start service async callback
 * 
 * @param       [in]  serverId
 * @param       [in]  serviceHandle
 * @param       [in]  errCode
 * @return      None
 */
typedef void (*SleHalStartServiceCallback)(uint8_t serverId, uint16_t serviceHandle, SleHalErrorCode errCode);

/**
 * @brief       Sle ssap remove all services async callback
 * 
 * @param       [in]  serverId
 * @param       [in]  errCode
 * @return      None
 */
typedef void (*SleHalRemoveAllServicesCallback)(uint8_t serverId, SleHalErrorCode errCode);

/**
 * @brief       Sle ssap receive read request event callback
 * 
 * @param       [in]  serverId
 * @param       [in]  connectId
 * @param       [in]  reqReadCbPara
 * @param       [in]  errCode
 * @return      None
 */
typedef void (*SleHalReceiveReadRequestCallback)(uint8_t serverId, uint16_t connectId, const SsapsReqReadCbParam *reqReadCbPara,
                SleHalErrorCode errCode);

/**
 * @brief       Sle ssap receive write request event callback
 * 
 * @param       [in]  serverId
 * @param       [in]  connectId
 * @param       [in]  reqWriteCbPara
 * @param       [in]  errCode
 * @return      None
 */
typedef void (*SleHalReceiveWriteRequestCallback)(uint8_t serverId, uint16_t connectId, const SsapsReqWriteCbPara *reqWriteCbPara,
                SleHalErrorCode errCode);

/**
 * @brief       Sle ssap receive mtu change event callback
 * 
 * @param       [in]  serverId
 * @param       [in]  mtuInfo
 * @param       [in]  errCode
 * @return      None
 */
typedef void (*SleHalChangeMtuCallback)(uint8_t serverId, uint16_t connectId ,const SsapMtuInfo *mtuInfo, SleHalErrorCode errCode);

typedef struct {
        SleHalStartServiceCallback              OnSsapsServiceStartedCb;
        SleHalRemoveAllServicesCallback         OnSsapsAllServiceRemovedCb;
        SleHalReceiveReadRequestCallback        OnSsapsRecvReadReqCb;
        SleHalReceiveWriteRequestCallback       OnSsapsRecvWriteReqCb;
        SleHalChangeMtuCallback                 OnSsapsMtuChangeCb;
} SleSsapsHalCallbacks;

/**
 * @brief       Initialize the sle ssap server hal.
 * 
 * @param       None
 * @return      SleHalErrorCode
 */
SleHalErrorCode InitSleSsapsHal(void);

/**
 * @brief       Deinitialize the sle ssap server hal.
 * 
 * @param       None
 * @return      SleHalErrorCode
 */
SleHalErrorCode DeinitSleSsapsHal(void);

/**
 * @brief       Add a ssap server
 * 
 * @param       [in]  appUuid
 * @param       [out] serverId
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalAddServer(const SleUuid *appUuid, uint8_t *serverId);

/**
 * @brief       remove a ssap server
 * 
 * @param       [in]  serverId
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalRemoveServer(uint8_t serverId);

/**
 * @brief       add a ssap service to the server
 * 
 * @param       [in]  serverId
 * @param       [in]  serviceUuid
 * @param       [in]  is_primary
 * @param       [out] serviceHandle 
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalAddService(uint8_t serverId, const SleUuid *serviceUuid, bool is_primary, uint16_t *serviceHandle);

/**
 * @brief       add a ssap property to the service
 * 
 * @param       [in]  serverId
 * @param       [in]  serviceHandle
 * @param       [in]  property
 * @param       [out] propertyHandle
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalAddProperty(uint8_t serverId, uint16_t serviceHandle, const  SsapsPropertyParam *property, uint16_t *propertyHandle);

/**
 * @brief       add a ssap descriptor to the property
 * 
 * @param       [in]  serverId
 * @param       [in]  serviceHandle
 * @param       [in]  propertyHandle
 * @param       [in]  descriptor
 * @param       [out] descriptorHandle
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalAddDescriptor(uint8_t serverId, uint16_t serviceHandle, uint16_t propertyHandle
        , const SsapsDescriptorParam *descriptor, uint16_t *descriptorHandle);

/**
 * @brief       start a ssap service
 * 
 * @param       [in]  serverId
 * @param       [in]  serviceHandle
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalStartService(uint8_t serverId, uint16_t serviceHandle);

/**
 * @brief       remove all service
 * 
 * @param       [in]  serverId
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalRemoveAllServices(uint8_t serverId);

/**
 * @brief       send a response to the client
 * 
 * @param       [in]  serverId
 * @param       [in]  connectId
 * @param       [in]  rspParam
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalSendResponse(uint8_t serverId, uint16_t connectId, const SsapsSendRspParam *rspParam);

/**
 * @brief       send a notify to the client
 * 
 * @param       [in]  serverId
 * @param       [in]  connectId
 * @param       [in]  notifyParam
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalNotifyIndicate(uint8_t serverId, uint16_t connectId, const SsapsNotifyParam *notifyParam);

/**
 * @brief       send a notify to the client by uuid
 * 
 * @param       [in]  serverId
 * @param       [in]  connectId
 * @param       [in]  notifyParam
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalNotifyIndicateByUuid(uint8_t serverId, uint16_t connectId, const SsapsNotyfyByUuidParam *notifyParam);

/**
 * @brief       send a notify to the client by uuid
 * 
 * @param       [in]  serverId
 * @param       [in]  mtuInfo
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalSetMtuInfo(uint8_t serverId, const SsapMtuInfo *mtuInfo);

/**
 * @brief       register the callback of the ssap server hal
 * 
 * @param       [in]  callback
 * @return      SleHalErrorCode
 */
SleHalErrorCode SleSsapsHalRegisterCallbacks(const SleSsapsHalCallbacks *callback);

#ifdef __cplusplus
}
#endif

#endif //SLE_SSAP_SERVER_HAL_H